package com.DTC;

import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArrayList;

public class NodeDis {
    public int type;       //0是叶子节点，1是分支结点
    
    //分支节点的属性
    public int attr;       //属性的index
    public Double mid;      //划分的中值
    
    //叶子结点的属性
    public Flower flowerType;

    public NodeDis left;
    public NodeDis right;

    public NodeDis(ArrayList<IrisEntry> data,ArrayList<Integer> needClass,CopyOnWriteArrayList<D> dList,CopyOnWriteArrayList<D> dOutList){
        int setNum = 0; //统计各个花的种类
        int verNum = 0;
        int virNum = 0;

        //统计各个种类的数量
        for (IrisEntry i : data) {
            switch(i.getFlowerType()){
                case setosa:{
                    setNum++;
                    break;
                }
                case versicolor:{
                    verNum++;
                    break;
                }
                case virginica:{
                    virNum++;
                    break;
                }
            }
        }
        if(setNum==data.size()){
            type=0;
            flowerType = Flower.setosa;
            left = null;
            right = null;
            return;
        }
        if(verNum==data.size()){
            type=0;
            flowerType = Flower.versicolor;
            left = null;
            right = null;
            return;
        }
        if(virNum==data.size()){
            type=0;
            flowerType = Flower.virginica;
            left = null;
            right = null;
            return;
        }

        if(needClass.size()==0){                //这里的判断D中样本在A上取值那个还没实现，先看看这样可以不可以
            type = 0;
            flowerType = getFlower(setNum,verNum,virNum);
            left = null;
            right = null;
            return;
        }

        CopyOnWriteArrayList<Integer> jobName = new CopyOnWriteArrayList<>();
        for (int i : needClass) {
            D d = D.allocateD(data, i);
            jobName.add(d.name);
            dList.add(d);
            // Divide divide = new Divide(data, i);
            // if(divide.gain > maxGain){
            //     maxAttr = i;
            //     maxmid = divide.mid;
            //     maxGain = divide.gain;
            // }
        }

        double maxmid = 0.0;
        int maxAttr = -1;
        double maxGain = -1;

        while(jobName.size()!=0){
            for (Integer integer : jobName) {
                for (D d : dOutList) {
                    if(d.getName()==integer && d.getState() ==2){
                        if(d.getGain() > maxGain){
                            maxAttr = d.getAttrIndex();
                            maxmid = d.getMid();
                            maxGain = d.getGain();
                        }
                        jobName.remove(integer);
                    }
                }
            }
        }

        
        ArrayList<Integer> newNeed1 = new ArrayList<>();
        ArrayList<Integer> newNeed2 = new ArrayList<>();
        for (Integer integer : needClass) {
            if(integer!=maxAttr){
                newNeed1.add(integer);
                newNeed2.add(integer);
            }
        }

        type = 1;
        attr = maxAttr;
        mid = maxmid;
        //划分左右数据集
        ArrayList<IrisEntry> leftData = new ArrayList<>();
        ArrayList<IrisEntry> rightData = new ArrayList<>();
        for (IrisEntry d : data) {
            if(d.getDataByArray()[attr] < mid){
                leftData.add(d);
            }else{
                rightData.add(d);
            }
        }

        left = new NodeDis(leftData, newNeed1,dList,dOutList);
        right = new NodeDis(rightData, newNeed2,dList,dOutList);


        return;
    }

    public void print(){
    }

    public static Flower getFlowerType(Double[] data,NodeDis root){
        NodeDis n = root;
        while(n.type==1){
            if(data[n.attr] > n.mid){
                n = n.right;
            }else{
                n = n.left;
            }
        }
        return n.flowerType;
    }

    private Flower getFlower(int setNum,int verNum,int virNum){
        if(setNum > verNum && setNum > virNum){
            return Flower.setosa;
        }else if(verNum>virNum){
            return Flower.versicolor;
        }else{
            return Flower.virginica;
        }
    }
}
